package com.zoe.onelink.test.container.support;

import com.zoe.onelink.test.container.support.ctr.init.ContainerEnvironmentInitializer;
import org.junit.jupiter.api.Assertions;
import org.testcontainers.containers.GenericContainer;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * <p>标题: </p>
 * <p>描述: </p>
 * <p>版权: Copyright (c) 2023</p>
 * <p>公司: 智业软件股份有限公司</p>
 *
 * @version: 1.0
 * @author: ruansheng
 * @date: 2023-01-13
 */
public class OnelinkContainerManager {

    private static final Map<String, GenericContainer<?>> CONTAINER_MAP = new ConcurrentHashMap<>();

    private static final Map<OnelinkContainerEnum, String> CONTAINER_DEFAULT_VERSION_MAP;

    static {
        CONTAINER_DEFAULT_VERSION_MAP = Map.of(
                OnelinkContainerEnum.ORACLE, "18.4.0-slim",
                OnelinkContainerEnum.MYSQL, "8.0",
                OnelinkContainerEnum.NACOS, "v2.1.2-slim",
                OnelinkContainerEnum.REDIS, "6.2.8"
        );
    }

    public static <T extends GenericContainer<?>> T startContainer(OnelinkContainerEnum onelinkContainerEnum) {
        return startContainer(onelinkContainerEnum, CONTAINER_DEFAULT_VERSION_MAP.get(onelinkContainerEnum));
    }

    @SuppressWarnings("unchecked")
    public static <T extends GenericContainer<?>> T startContainer(OnelinkContainerEnum onelinkContainerEnum, String tag) {
        Assertions.assertNotNull(tag);
        String containerImage = onelinkContainerEnum.getImageName() + ":" + tag;
        return (T) CONTAINER_MAP.computeIfAbsent(containerImage, imgName -> {
            GenericContainer<?> container = OnelinkContainerFactory.create(onelinkContainerEnum, tag);
            if (container instanceof ContainerEnvironmentInitializer) {
                ContainerEnvironmentInitializer containerInitializer = (ContainerEnvironmentInitializer) container;
                containerInitializer.preStart();
                container.start();
                containerInitializer.afterStarted();
            } else {
                container.start();
            }
            return container;
        });

    }

}
